package com.lcf.system.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.baomidou.mybatisplus.extension.toolkit.Db;
import com.lcf.framework.exception.SysException;
import com.lcf.framework.utils.UserUtils;
import com.lcf.framework.vo.PageVO;
import com.lcf.system.dao.SysTenantRuleDao;
import com.lcf.system.dto.SysTenantRuleDTO;
import com.lcf.system.entity.RoleDetail;
import com.lcf.system.entity.RuleUser;
import com.lcf.system.entity.SysTenantRule;
import com.lcf.system.enums.RuleStatusEnum;
import com.lcf.system.query.SysTenantRulePageQuery;
import com.lcf.system.service.SysTenantRuleService;
import com.lcf.system.vo.RoleDetailVO;
import com.lcf.system.vo.SysTenantRulePageVO;
import com.lcf.system.vo.SysTenantRuleVO;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.LocalDate;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 团购规则(SysTenantRule)表服务实现类
 *
 * @author lcf
 * @since 2025-05-02 11:55:04
 */
@Service("sysTenantRuleService")
public class SysTenantRuleServiceImpl extends ServiceImpl<SysTenantRuleDao, SysTenantRule> implements SysTenantRuleService {

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean save(SysTenantRuleDTO dto) {
        SysTenantRule sysTenantRule = BeanUtil.copyProperties(dto, SysTenantRule.class);
        sysTenantRule.setUserId(UserUtils.getUserId());
        sysTenantRule.setStatus(RuleStatusEnum.RUNNING.getCode());
        if (dto.getEndTime().isBefore(LocalDate.now())) {
            sysTenantRule.setStatus(RuleStatusEnum.END.getCode());
        }
        if (dto.getStartTime().isAfter(LocalDate.now())) {
            sysTenantRule.setStatus(RuleStatusEnum.WAIT_START.getCode());
        }

        sysTenantRule.setIsOrder(0);
        sysTenantRule.insert();

        dto.getDetails().forEach(detail -> {
            RoleDetail roleDetail = BeanUtil.copyProperties(detail, RoleDetail.class);
            roleDetail.setRuleId(sysTenantRule.getId());
            roleDetail.insert();
        });

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean update(long id, SysTenantRuleDTO dto) {
        SysTenantRule sysTenantRule = getById(id);
        if (!Objects.equals(sysTenantRule.getStatus(), RuleStatusEnum.WAIT_START.getCode())) {
            throw new SysException("活动已开始");
        }
        if (Objects.equals(sysTenantRule.getIsOrder(), 1)) {
            throw new SysException("活动已结束");
        }

        SysTenantRule tenantRule = BeanUtil.copyProperties(dto, SysTenantRule.class);
        sysTenantRule.setStatus(RuleStatusEnum.RUNNING.getCode());
        if (dto.getEndTime().isBefore(LocalDate.now())) {
            sysTenantRule.setStatus(RuleStatusEnum.END.getCode());
        }
        if (dto.getStartTime().isAfter(LocalDate.now())) {
            sysTenantRule.setStatus(RuleStatusEnum.WAIT_START.getCode());
        }
        tenantRule.setId(id);
        tenantRule.updateById();

        Db.lambdaUpdate(RoleDetail.class).eq(RoleDetail::getRuleId, id).remove();

        dto.getDetails().forEach(detail -> {
            RoleDetail roleDetail = BeanUtil.copyProperties(detail, RoleDetail.class);
            roleDetail.setRuleId(sysTenantRule.getId());
            roleDetail.insert();
        });

        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean remove(long id) {
        removeById(id);
        Db.lambdaUpdate(RoleDetail.class).eq(RoleDetail::getRuleId, id).remove();

        return true;
    }

    @Override
    public SysTenantRuleVO getDetail(long id) {
        SysTenantRule sysTenantRule = getById(id);
        SysTenantRuleVO sysTenantRuleVO = BeanUtil.copyProperties(sysTenantRule, SysTenantRuleVO.class);

        List<RoleDetail> list = Db.lambdaQuery(RoleDetail.class).eq(RoleDetail::getRuleId, id).list();
        sysTenantRuleVO.setDetailList(BeanUtil.copyToList(list, RoleDetailVO.class));

        List<RuleUser> rulelist = Db.lambdaQuery(RuleUser.class)
                .eq(RuleUser::getRuleId, id)
                .list();

        long userId = UserUtils.getUserId();
        sysTenantRuleVO.setSignNum(rulelist.size());
        sysTenantRuleVO.setIsSign(rulelist.stream().anyMatch(ruleUser -> ruleUser.getUserId().equals(userId)) ? 1 : 0);

        return sysTenantRuleVO;
    }

    @Override
    public PageVO<SysTenantRulePageVO> page(SysTenantRulePageQuery query) {
        Page<SysTenantRule> page = Db.lambdaQuery(SysTenantRule.class)
                .eq(query.getGoodsId() != null, SysTenantRule::getGoodsId, query.getGoodsId())
                .eq(query.getStatus() != null, SysTenantRule::getStatus, query.getStatus())
                .like(StringUtils.isNotBlank(query.getRuleName()), SysTenantRule::getRuleName, query.getRuleName())
                .orderByDesc(SysTenantRule::getCreateTime)
                .page(query.toPage());

        if (CollectionUtils.isEmpty(page.getRecords())) {
            return new PageVO<>(page, SysTenantRulePageVO.class);
        }

        PageVO<SysTenantRulePageVO> result = new PageVO<>(page, SysTenantRulePageVO.class);

        List<Long> ruleIdlist = page.getRecords().stream().map(SysTenantRule::getId).toList();

        List<RuleUser> rulelist = Db.lambdaQuery(RuleUser.class)
                .in(RuleUser::getRuleId, ruleIdlist)
                .list();

        Map<Long, List<RoleDetail>> detailMap = Db.lambdaQuery(RoleDetail.class)
                .in(RoleDetail::getRuleId, ruleIdlist).list()
                .stream().collect(Collectors.groupingBy(RoleDetail::getRuleId));

        long userId = UserUtils.getUserId();
        List<Long> userRuleIdList = rulelist.stream()
                .filter(x -> Objects.equals(x.getUserId(), userId))
                .map(RuleUser::getRuleId).toList();

        Map<Long, List<RuleUser>> collect = rulelist.stream().collect(Collectors.groupingBy(RuleUser::getRuleId));
        result.getList().forEach(rule -> {
            rule.setIsSign(userRuleIdList.contains(rule.getId()) ? 1 : 0);
            if (collect.get(rule.getId()) != null) {
                rule.setSignNum(collect.get(rule.getId()).size());
            } else {
                rule.setSignNum(0);
            }

            rule.setDetailList(BeanUtil.copyToList(detailMap.get(rule.getId()), RoleDetailVO.class));
        });

        return result;
    }
}

